{-
    pHaskell Translator v0.1 
    Copyright (C) 2009  Ruben Marcelo Caro 

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-}
module PHaskellTypes where
 
data HaskellType = Bool | Int | Arrow HaskellType HaskellType | UserDef String | Unknown
						deriving (Eq,Show)

type TypeDefinition = (String, HaskellType) 

data Exp = 
       App Exp Exp
     | Integer String 
	 | Variable String
	 | Boolean String
	 | Lambda Exp HaskellType Exp   --nombre de la var, tipo, exprecion 
	 | If Exp Exp Exp  
	 | IfOnly Exp Exp 
        deriving (Eq,Show)	  				   

data ConstructorType = ConstructorType String [HaskellType]
							deriving (Eq,Show)

data SuperCombinator =   TypeDefinitionSc TypeDefinition 
					   | UserTypeDefinition String [ConstructorType] -- Nombre del tipo, lista de constructores
                       | FunctionDefinitionSc String [Exp] Exp Program --Function Name, [variables name, matching expresion], Expresion, locals def
                       | GeneratrixTunneling Generatrix
                       		deriving (Eq,Show)

data Generatrix = Generatrix  [String] String [Exp] [CArg] CExp -- return type, funcion name,  argument list, Cargs, Codegenerator
					deriving (Eq,Show) 

type Program           = [SuperCombinator]
type GeneratrixProgram = [Generatrix]


 
isSuperCombinator (GeneratrixTunneling _) 	= False
isSuperCombinator _ 						= True
 
isGeneratrixTunneling (GeneratrixTunneling _) 	= True
isGeneratrixTunneling _ 						= False
 

{-Selector de Type Definitions-}
isTypeDefinition::SuperCombinator -> Bool
isTypeDefinition (TypeDefinitionSc _) = True
isTypeDefinition        _             = False

isFunctionDefinition::SuperCombinator -> Bool
isFunctionDefinition (FunctionDefinitionSc _ _ _ _ ) = True
isFunctionDefinition        _                        = False


isUserTypeDefinition::SuperCombinator -> Bool
isUserTypeDefinition (UserTypeDefinition _ _ ) = True
isUserTypeDefinition        _                  = False

--Traduce las guardas a IfOnly o If
expandGuard [(e,e')] = IfOnly e e' 
expandGuard ((Boolean "true",e'):es)  =  e'
expandGuard ((Boolean "false",e'):es) =  expandGuard es
expandGuard ((e,e'):es) =  If e e' (expandGuard es)  

--types utils
sourceType ( Arrow t1 t2 ) = t1
sourceType  t = t
destinationType ( Arrow t1 t2 ) = t2
destinationType t               = Unknown


--Parser Util
--makeApplicaionFromList es = makeApplicaionFromList' (reverse (es++[(Variable "metaemptylist")]))

makeApplicaionFromList []    = Variable "metaemptylist"
makeApplicaionFromList (e:es) = App (App (Variable "metalist") e) (makeApplicaionFromList es) 


-- ======================================== Generatrices ====================================



data CExp =     CodeVariable String
               |CodeNumber   String
               |CodeBoolean  String
               |CodeBinaryOpMult CExp CExp
               |CodeBinaryOpDiv CExp CExp
               |CodeBinaryOpAdd CExp CExp
               |CodeBinaryOpLogicAnd CExp CExp
               |CodeBinaryOpLogicOr CExp CExp
               |CodeBinaryOpLogicXor CExp CExp
               |CodeBinaryOpMinus CExp CExp
               |CodeBinaryAssign CExp CExp
               |CodeArraySubscript CExp CExp
               |CodeBinaryOpShiftLeft CExp CExp
               |CodeBinaryOpShiftRight CExp CExp
               |CodeBinaryNotEq CExp CExp
               |CodeBinaryEq CExp CExp
               |CodeStaticAccess  CExp CExp  -- ::
               |CodeClassAccess   CExp CExp  -- .
               |CodeFunctionCall  CExp [CExp]
               |CodePHaskellExp  Exp
               |CodeIf CExp CExp CExp  -- ?:
               |CodeTemplateInst CExp [CExp]  -- exp<, , ,>
               |CodeGeneratrixCall String [Exp] [CExp]
               |CodeString String
               |CodeSequense CExp CExp
               |CodeUnaryLNot CExp
               |CodeParent CExp
               		deriving (Eq,Show)

makeCargs [] = NoCArg
makeCargs xs = CArg (init xs) (last xs)


data CArg = CArg [String] String  -- tipos variable name
			|NoCArg
				deriving (Eq,Show)